package com.example.smartwaterapi.config;

import com.example.smartwaterapi.security.JwtAuthenticationEntryPoint;
import com.example.smartwaterapi.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security配置类
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    private final JwtAuthenticationEntryPoint unauthorizedHandler;
    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    // 使用构造器注入替代字段注入
    public SecurityConfig(
            JwtAuthenticationEntryPoint unauthorizedHandler,
            @Lazy JwtAuthenticationFilter jwtAuthenticationFilter) { // 添加@Lazy注解
        this.unauthorizedHandler = unauthorizedHandler;
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    /**
     * 配置安全过滤器链
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 禁用CSRF，因为使用JWT
        http.csrf(AbstractHttpConfigurer::disable)
            // 禁用HTTP响应头
            .headers(headers -> headers.cacheControl(cache -> cache.disable())
                    .frameOptions(frame -> frame.disable()))
            // 认证失败处理类
            .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
            // 禁用session，使用JWT
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // 配置路径权限
            .authorizeHttpRequests(auth -> auth
                    // 公开接口
                    .requestMatchers(
                            // Swagger相关接口
                            "/v3/api-docs/**",
                            "/swagger-ui/**",
                            "/swagger-ui.html",
                            "/doc.html",
                            // 认证相关接口
                            "/api/auth/login",
                            "/api/auth/register",
                            "/api/user/login",
                            "/api/user/register",
                            "/api/wechat/login",
                            "/api/wechat/login/phone",
                            // 微信模板消息测试接口
                            "/api/wechat/template/**",
                            "/api/wechat/subscribe/**",
                            "/api/wechat/official/**",
                            // 微信网页授权接口
                            "/wechat/auth/**",
                            // 天气API接口
                            "/api/weather/**",
                            // 系统测试接口（开发环境使用）
                            "/api/system/test/**",
                            // 文件传输相关接口（全部放行）
                            "/api/file/**",
                            "/api/files/**",
                            // 静态资源
                            "/favicon.ico",
                            "/static/**",
                            // 验证文件（域名验证等）
                            "/mOm4kNn8Pf.txt",
                            "/*.txt",
                            // 健康检查
                            "/actuator/**",
                            // 错误页面
                            "/error"
                    ).permitAll()
                    // 其他所有请求需要认证
                    .anyRequest().authenticated()
            );

        // 添加JWT过滤器
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    /**
     * 密码编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 认证管理器
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }
}